package org.mbds.android.emsc.seismicportal;

import java.util.ArrayList;

/**
 * QuakeML
 * @author Anne-Marie Lesas
 * Keywords of QuakeML for Web services result filter
 */
public class QuakeML {

	//////////////////////////////////////////////////////////////////
	// Web services filter keywords///////////////////////////////////
	//////////////////////////////////////////////////////////////////
	/*
	 * limit to events occurring on or after the specified start time.Examples: starttime=2012-11-29 or 2012-11-29T00:00:00 or 2012-11-29T00:00:00.000
	 */
	public static String STARTTIME = "starttime="; 
	/*
	 * limit to events occurring on or before the specified end time
	 */
	public static String ENDTIME = "endtime";
	/*
	 * southern boundary (double)
	 */
	public static String MINLATITUDE = "minlatitude";
	/*
	 * northern boundary (double)
	 */
	public static String MAXLATITUDE = "maxlatitude";
	/*
	 * western boundary (double)
	 */
	public static String MINLONGITUDE = "minlongitude";
	/*
	 * eastern boundary (double)
	 */
	public static String MAXLONGITUDE = "maxlongitude";
	/*
	 * Limit to events with a magnitude larger than or equal to the specified minimum (double)
	 */
	public static String MINMAGNITUDE = "minmagnitude";
	/*
	 * Limit to events with a magnitude smaller than or equal to the specified maximum (double)
	 */
	public static String MAXMAGNITUDE = "maxmagnitude";
	/*
	 * Type of Magnitude used to test minimum and maximum limits (case insensitive). Examples: Ml,Ms,mb,Mw
	 */
	public static String MAGTYPE = "magtype";
	/*
	 * Specify the catalog from which origins and magnitudes will be retrieved. See available catalogs at : http://www.seismicportal/fdsnws/event/1/catalogs
	 */
	public static String CATALOG = "catalog";
	/*
	 * Limit to events contributed by a specified contributor. See available catalogs at : http://www.seismicportal/fdsnws/event/1/contributors
	 */
	public static String CONTRIBUTOR = "contributor";
	/*
	 * Limit to events with depths equal to or less than the specified depth (double)
	 */
	public static String MAXDEPTH = "maxdepth";
	/*
	 * Limit to events with depths equal to or greater than the specified depth (double)
	 */
	public static String MINDEPTH = "mindepth";
	/*
	 * Specify the central latitude point for a radial search (double)
	 */
	public static String LATITUDE = "latitude";
	/*
	 * Specify the central longitude point for a radial search (double)
	 */
	public static String LONGITUDE = "longitude";
	/*
	 * Specify maximum distance from the geographic point defined by latitude and longitude (double)
	 */
	public static String MAXRADIUS = "maxradius";
	/*
	 * Specify minimum distance from the geographic point defined by latitude and longitude (double)
	 */
	public static String MINRADIUS = "minradius";
	/*
	 * Limit to events updated after the specified time (date)
	 */
	public static String UPDATEAFTER = "updatedafter";
	/*
	 * One of: time (default), magnitude, time-asc, magnitude-asc
	 */
	public static String ORDERBY = "orderby";
	
	public static String ORDERBY_TIME_DESC = "time" ;
	public static String ORDERBY_MAGNITUDE_DESC = "magnitude";
	public static String ORDERBY_TIME_ASC = "time-asc";
	public static String ORDERBY_MAGNITUDE_ASC = "magnitude-asc";
	/*
	 *  Event ID (long)
	 */
	public static String EVENTID = "eventid";
	/*
	 * Include arrivals. Default: false (boolean) 
	 */
	public static String INCLUDEARRIVALS = "includearrivals";
	/*
	 * Include magnitudes. Default: false (boolean) 
	 */
	public static String INCLUDEALLMAGNITUDES = "includeallmagnitudes";
	/*
	 * Include all origins. Default: false (boolean) 
	 */
	public static String INCLUDEALLORIGINS = "includeallorigins";
	/*
	 * Limit records (int) 
	 */
	public static String LIMIT = "limit";
	/*
	 * Return results starting at the event count specified (int) 
	 */
	public static String OFFSET = "offset";
	/*
	 * Specify output format. This is an EMSC extension to the FDSN specification
	 * One of: quakeml (default), json, jsonp 
	 */
	public static enum FORMAT_VALUE {
		quakeml, json, jsonp
	}
	public static String FORMAT = "format";
	/*
	 * Javascript callback method name. used when output format is jsonp. This is an EMSC extension to the FDSN specification 
	 */
	public static String CALLBACK = "callback";
	
	//////////////////////////////////////////////////////////////////
	// QuakeML keywords //////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////

	public static String ROOT_QUAKEML = "q:quakeml";
	public static String ELEMENT_EVENTPARAMETERS = "eventParameters ";
	public static String ELEMENT_EVENT = "event ";
	public static String ATTRIBUT_PUBLC_ID = "publicID";
	public static String ELEMENT_PREFERRED_ORIGIN_ID = "preferredOriginID";
	public static String ELEMENT_PREFERRED_MAGNITUDE_ID = "preferredMagnitudeID";
	public static String ELEMENT_TYPE = "type";
	public static String ELEMENT_CREATION_INFO = "creationInfo";
	public static String ELEMENT_AGENCY_URI = "agencyURI";
	public static String ELEMENT_AUTHOR_URI = "authorURI";
	public static String ELEMENT_CREATION_TIME = "creationTime";
	public static String ELEMENT_DESCRIPTION = "description";
	public static String ELEMENT_TEXT = "text";
	public static String ELEMENT_ORIGIN = "origin";
	public static String ELEMENT_TIME = "time";
	public static String ELEMENT_VALUE = "value";
	public static String ELEMENT_LATITUDE = "latitude";
	public static String ELEMENT_LONGITUDE = "longitude";
	public static String ELEMENT_DEPTH = "depth";
	public static String ELEMENT_DEPTH_TYPE = "depthType";
	public static String ELEMENT_METHOD_ID = "methodID";
	public static String ELEMENT_QUALITY = "quality";
	public static String ELEMENT_USE_PHASE_COUNT = "usedPhaseCount";
	public static String ELEMENT_STANDARD_ERROR = "standardError";
	public static String ELEMENT_AZIMUTHAL_GAP = "azimuthalGap";
	public static String ELEMENT_MINIMUM_DISTANCE = "minimumDistance";
	public static String ELEMENT_EVALUATION_MODE = "evaluationMode";
	public static String ELEMENT_MAGNITUDE = "magnitude";
	public static String ELEMENT_MAG = "mag";
	public static String ELEMENT_ORIGIN_ID = "originID";
	
	//////////////////////////////////////////////////////////////////
	// get values from QuakeML String ////////////////////////////////
	//////////////////////////////////////////////////////////////////

	public static ArrayList<SeismicEvent> getEvents(String xmlText) {
		ArrayList<SeismicEvent> eventsList = new ArrayList<SeismicEvent>();
		int idx1 = xmlText.indexOf("<"+ELEMENT_EVENTPARAMETERS);
		int idx2 = xmlText.lastIndexOf("<"+"/"+ELEMENT_EVENTPARAMETERS);
		if (idx1<=0 || idx2<=0) return eventsList; // Malformed QakeML text
		String text = xmlText.substring(idx1, idx2);
		while (text.length()>0) {
			idx1=text.indexOf("<"+ELEMENT_EVENT);
			idx2=text.indexOf("<"+"/"+ELEMENT_EVENT);
			if (idx1<=0 || idx2<=0) break;
			String xmlEvent = text.substring(idx1, idx2);
			text = xmlEvent.replace(xmlEvent, "");
			idx1=xmlEvent.indexOf(ATTRIBUT_PUBLC_ID)+ATTRIBUT_PUBLC_ID.length()+1;
			idx2=xmlEvent.indexOf(""+">")-1;
			String publicID = xmlEvent.substring(idx1, idx2);
			text=xmlEvent.substring(0, idx2+2);
			idx1=xmlEvent.indexOf(ELEMENT_TYPE)+ELEMENT_TYPE.length()+1;
			idx2=xmlEvent.indexOf("</"+ELEMENT_TYPE)-1;
			String type = xmlEvent.substring(idx1, idx2);
			text=xmlEvent.substring(0, idx2+ELEMENT_TYPE.length()+1);
			idx1=xmlEvent.indexOf(ELEMENT_TEXT)+ELEMENT_TEXT.length()+1;
			idx2=xmlEvent.indexOf("</"+ELEMENT_TEXT)-1;
			String description1 = xmlEvent.substring(idx1, idx2);;
			text=xmlEvent.substring(0, idx2+ELEMENT_TEXT.length()+1);
			idx1=xmlEvent.indexOf(ELEMENT_TYPE)+ELEMENT_TYPE.length()+1;
			idx2=xmlEvent.indexOf("</"+ELEMENT_TYPE)-1;
			String description2 = xmlEvent.substring(0, idx2+ELEMENT_TYPE.length()+1);
			text=xmlEvent.substring(0, idx2+ELEMENT_TYPE.length()+1);
			idx1=xmlEvent.indexOf(ELEMENT_TIME)+ELEMENT_TIME.length()+1;
			idx2=xmlEvent.indexOf("</"+ELEMENT_TIME)-1;
			String text2 = xmlEvent.substring(idx1,idx2);
			idx1=text2.indexOf(ELEMENT_VALUE)+ELEMENT_VALUE.length()+1;
			idx2=text2.indexOf("</"+ELEMENT_VALUE)-1;
			String datetime = text2.substring(idx1,idx2);
			idx1=xmlEvent.indexOf(ELEMENT_LATITUDE)+ELEMENT_LATITUDE.length()+1;
			idx2=xmlEvent.indexOf("</"+ELEMENT_LATITUDE)-1;
			text2 = xmlEvent.substring(idx1,idx2);
			idx1=text2.indexOf(ELEMENT_VALUE)+ELEMENT_VALUE.length()+1;
			idx2=text2.indexOf("</"+ELEMENT_VALUE)-1;
			double latitude = new Double(text2.substring(idx1,idx2)).doubleValue();
			idx1=xmlEvent.indexOf(ELEMENT_LONGITUDE)+ELEMENT_LONGITUDE.length()+1;
			idx2=xmlEvent.indexOf("</"+ELEMENT_LONGITUDE)-1;
			text2 = xmlEvent.substring(idx1,idx2);
			idx1=text2.indexOf(ELEMENT_VALUE)+ELEMENT_VALUE.length()+1;
			idx2=text2.indexOf("</"+ELEMENT_VALUE)-1;
			double longitude = new Double(text2.substring(idx1,idx2)).doubleValue();
			idx1=xmlEvent.indexOf(ELEMENT_MAG)+ELEMENT_MAG.length()+1;
			idx2=xmlEvent.indexOf("</"+ELEMENT_MAG)-1;
			text2 = xmlEvent.substring(idx1,idx2);
			idx1=text2.indexOf(ELEMENT_VALUE)+ELEMENT_VALUE.length()+1;
			idx2=text2.indexOf("</"+ELEMENT_VALUE)-1;
			double magnitude = new Double(text2.substring(idx1,idx2)).doubleValue();
			eventsList.add(new SeismicEvent(publicID, type, description1, description2, datetime, latitude, longitude, magnitude));
		}
		return eventsList;
	}
}
